/*************************************************************************************
* Copyright (c) 2021 xffish
* c_plus_plus_primer_exercise is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*************************************************************************************/

#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

//照搬书本P456，P457，默写
class HasPtr
{
public:
//取消了explicit
    HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0),use(new std::size_t(1))
    {}
    HasPtr(const HasPtr& rhp):ps(rhp.ps),i(rhp.i),use(rhp.use)
    {
        ++*use;
    }
    HasPtr& operator=(const HasPtr& rhp)
    {
        ++*rhp.use;
        --*use;
        if(*use == 0)
        {
            delete ps;
            delete use;
        }
        ps = rhp.ps;
        i = rhp.i;
        use = rhp.use;

        return *this;
    }
    ~HasPtr()
    {
        --*use;
        if(*use == 0)
        {
            delete ps;
            delete use;
        }
    }
    void showInfo()
    {
        cout << "ps:" << *ps << ",ps's address:" << ps << ",use:" << *use << endl;
    }
private:
    string *ps;
    int i;
    std::size_t *use;
};

int main()
{
    HasPtr hp1("apple");
    HasPtr hp2 = hp1;
    HasPtr hp3(hp1);
    hp1.showInfo();
    hp2.showInfo();
    hp3.showInfo();
    HasPtr hp4("banana");
    hp4.showInfo();
    hp4 = hp3;
    hp4.showInfo();
    HasPtr hp5 = string("chery");
    hp5.showInfo();
    return 0;
}